package com.GPT.service.impl;

import com.GPT.common.Jwt;
import com.GPT.common.Result;
import com.GPT.common.UserId;
import com.GPT.dao.UsersMapper;
import com.GPT.domain.Newuser;
import com.GPT.domain.UserVo;
import com.GPT.service.UserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.sql.Date;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

import static com.GPT.common.ValidateCodeUtils.generateValidateCode;

@Service
public class UserServiceImpl extends ServiceImpl<UsersMapper, Newuser> implements UserService {

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Override
    public Result login(Newuser newuser) {
        //1、将页面提交的密码password进行md5加密处理
        String password = newuser.getPasswordHash();
        password = DigestUtils.md5DigestAsHex(password.getBytes());
        //2、根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<Newuser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Newuser::getEmail,newuser.getEmail());
        Newuser emp = getOne(queryWrapper);
        //3、如果没有查询到则返回登录失败结果
        if(emp == null){
            return Result.error("账号不存在！请注册");
        }
        //4、密码比对，如果不一致则返回登录失败结果
        if(!emp.getPasswordHash().equals(password)){
            return Result.error("密码错误");
        }
        //6、登录成功，生成 JWT token存入并返回登录成功结果
        String token = Jwt.generateToken(emp.getId());
        return Result.success(token,"登录成功");
    }

    @Override
    public Result saveRegister(UserVo userVo) {
        //根据页面提交的用户名username查询数据库
        LambdaQueryWrapper<Newuser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Newuser::getEmail,userVo.getEmail());
        Newuser emp = getOne(queryWrapper);
        if (emp!=null){
            return Result.error("账号已注册");
        }
        //检验验证码是否正确
        /*String codeFromRedis = redisTemplate.opsForValue().get(userVo.getEmail()); // 从 Redis 获取验证码
        if (codeFromRedis == null || !codeFromRedis.equals(userVo.getCode())) { // 比较 Redis 中的验证码和用户提交的验证码
            return Result.error("验证码无效或已过期");
        }*/
        Newuser newuser=new Newuser();
        //设置账号
        newuser.setEmail(userVo.getEmail());
        //设置密码，需要进行md5加密处理
        newuser.setPasswordHash(DigestUtils.md5DigestAsHex(userVo.getPasswordHash().getBytes()));
        // 验证code邀请码不重复
        String code;
        boolean isUnique=true;
        do{
            code = String.valueOf(generateValidateCode(4));
            LambdaQueryWrapper<Newuser> userLQW = new LambdaQueryWrapper<>();
            userLQW.eq(code!=null,Newuser::getCode, code);
            Newuser user = getOne(userLQW);
            if (user==null){
                isUnique=false;
            }
        }while (isUnique);
        //设置验证码
        newuser.setCode(code);
        boolean save = save(newuser);
        if (save==true){
            return Result.success("1","注册成功" );
        }else {
            return Result.error("注册失败");
        }
    }

    @Override
    public Result validateInviteCode(HttpServletRequest request,String code) {
        LambdaQueryWrapper<Newuser> userLQW = new LambdaQueryWrapper<>();
        // 设置查询条件：code 不为空且匹配指定的值
        userLQW.isNotNull(Newuser::getCode)
                .eq(Newuser::getCode, code);
        // 执行查询操作
        Newuser user = getOne(userLQW);
        if (user != null) {
            // 检查用户是否是新用户（注册时间在三天内）
            Long userId = new UserId().getUserId(request);//获取当前登录用户ID
            // 检查邀请码是否已经使用过
            if (getById(userId).getIsInviteCodeUsed()==0) {
                return Result.error("只能使用一次邀请码");
            }
            // 获取当前时间// 计算三天前的日期和时间
            Date createTime = getById(userId).getCreateTime();
            LocalDateTime registrationDate = createTime.toLocalDate().atStartOfDay();
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime threeDaysAgo = now.minus(3, ChronoUnit.DAYS);
            if (registrationDate.isBefore(threeDaysAgo) || registrationDate.isEqual(threeDaysAgo)) {
                return Result.error("用户注册超过三天，无法使用邀请码");
            }
            if (getById(userId).getCode().equals(code)){
                return Result.error("不能输入自己的邀请码");
            }
            // 增加token的逻辑
            BigDecimal balance = new BigDecimal(user.getBalance());
            // 创建一个 BigDecimal 表示增加的金额
            BigDecimal amountToAdd = new BigDecimal("20.00");
            // 计算新的余额
            BigDecimal newBalance = balance.add(amountToAdd);
            // 将新的余额转换回字符串
            String newBalanceStr = newBalance.toString();
            user.setBalance(newBalanceStr);
            user.setIsInviteCodeUsed(1);
            boolean save = updateById(user);
            if (save){
                // 标记邀请码被使用
                return Result.msg("邀请成功,问答次数+20");
            }else {
                return Result.error("邀请码失效");
            }
        } else {
            return Result.error("用户不存在");
        }
    }

}
